package com.zyf.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;

/**
 * @author Malegod_xiaofei
 * @create 2021-12-20-22:46
 * 客户端代码常用套路
 * 1、获取一个客户端对象
 * 2、执行相关的操作命令
 * 3、关闭资源
 * HDFS Zookeeper
 */
public class HdfsClient {

    private FileSystem fs;

    @Before
    public void init() throws Exception {
        // 连接的集群地址
        URI uri = new URI("hdfs://hadoop102:8020");
        // 创建一个配置文件
        Configuration configuration = new Configuration();

        configuration.set("dfs.replication", "2");
        // 用户
        String user = "malegod-xiaofei";

        // 1、获取到了客户端的对象
        fs = FileSystem.get(uri, configuration, user);

    }

    @After
    public void close() throws Exception {
        // 3、关闭资源
        fs.close();
    }

    // 创建目录
    @Test
    public void testmkdir() throws Exception {

        // 2、创建一个文件夹
        fs.mkdirs(new Path("/xiyou/huaguoshan1"));

    }

    // 上传

    /**
     * 参数优先级
     * hdfs-default.xml => hdfs-site.xml => 在项目资源目录下的配置文件 => 代码里面的配置
     * 从左到右，从低到高
     *
     * @throws Exception
     */

    @Test
    public void testPut() throws Exception {
        // 参数解读:参数一:表示删除原数据;    参数二:是否允许覆盖;     参数三：原数据路径；  参数四：目的地路径
        /*fs.copyFromLocalFile(false, true
                , new Path("D:\\Modules\\Hadoop\\04_jar包\\hadoop-3.1.3.tar.gz")
                , new Path("/xiyou/huaguoshan"));*/
        fs.copyFromLocalFile(false, true
                , new Path("E:\\Test\\sunwukong.txt")
                , new Path("/xiyou/huaguoshan1"));
    }

    // 文件下载
    @Test
    public void testGet() throws Exception {
        // 参数的解读:参数一:原文件是否删除;   参数二:原文件路径HDFS;  参数三：目的地路径Win；  参数四：
        /*fs.copyToLocalFile(true
                , new Path("/xiyou/huaguoshan1")
                , new Path("E:\\Test")
                , false);*/
        fs.copyToLocalFile(false
                , new Path("/a.txt")
                , new Path("E:\\Test")
                , false);
    }

    // 删除
    @Test
    public void testRm() throws Exception {
        // 参数解读：参数一：要删除的文件路径；  参数二：是否递归删除
        // 删除文件
        // fs.delete(new Path("/jdk-8u212-linux-x64.tar.gz"), true);

        // 删除空目录
        // fs.delete(new Path("/xiyou1"), true);

        // 删除非空目录
        fs.delete(new Path("/xiyou1"), true);

    }

    // 文件的更名和移动
    @Test
    public void testMv() throws Exception {
        // 参数解读：参数一：原文件路径；  参数二：目标文件路径
        // 对文件名称的修改
        // fs.rename(new Path("/input/word.txt"), new Path("/input/ss.txt"));

        // 对文件的移动和更名
        // fs.rename(new Path("/input/ss.txt"), new Path("/canglaoshi.txt"));

        // 目录更名
        fs.rename(new Path("/input"), new Path("/output"));
    }

    // 获取文件详细信息
    @Test
    public void testListFiles() throws Exception {
        // 获取所有文件信息
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

        // 遍历文件
        while (listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();

            System.out.println("==========" + fileStatus.getPath() + "==========");
            System.out.println(fileStatus.getPermission());
            System.out.println(fileStatus.getOwner());
            System.out.println(fileStatus.getGroup());
            System.out.println(fileStatus.getLen());
            System.out.println(fileStatus.getModificationTime());
            System.out.println(fileStatus.getReplication());
            System.out.println(fileStatus.getBlockSize());
            System.out.println(fileStatus.getPath().getName());

            // 获取块信息
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println(Arrays.toString(blockLocations));
        }
    }

    // 判断是文件夹还是文件
    @Test
    public void testFile() throws Exception {
        FileStatus[] listStatus = fs.listStatus(new Path("/"));

        for (FileStatus status : listStatus) {

            if (status.isFile()) {
                System.out.println("文件：" + status.getPath().getName());
            } else {
                System.out.println("目录：" + status.getPath().getName());
            }
        }
    }
}
